<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="XrYtZ" id="XrYtZ"><span data-lake-id="ue6929d4c" id="ue6929d4c">典型回答</span></h1>
  <p data-lake-id="u7b17aa04" id="u7b17aa04"><br></p>
  <p data-lake-id="uf2f897c9" id="uf2f897c9"><span data-lake-id="ubeb2d881" id="ubeb2d881">在Zookeeper中，watch机制是一种非常重要的特性，它能够让应用程序监听Zookeeper上节点的变化，从而及时做出响应。</span></p>
  <p data-lake-id="u6df2c5f3" id="u6df2c5f3"><span data-lake-id="u59c3f4ac" id="u59c3f4ac">​</span><br></p>
  <p data-lake-id="ub05141ec" id="ub05141ec"><span data-lake-id="u48982ad6" id="u48982ad6">Zookeeper的watch机制实现中，涉及到多个概念，首先是客户端和服务端，这个好理解，Zookeeper的集群就是服务端，调用ZK服务的机器就是客户端。</span></p>
  <p data-lake-id="ub15a6735" id="ub15a6735"><span data-lake-id="uc7e83168" id="uc7e83168">​</span><br></p>
  <p data-lake-id="uab9ae0e9" id="uab9ae0e9"><span data-lake-id="ub8b6d786" id="ub8b6d786">还有两个模块，</span><strong><span data-lake-id="u7ce0d81e" id="u7ce0d81e">分别叫做WatchManager和ZkWatcherManager。</span></strong></p>
  <p data-lake-id="u02bd1f15" id="u02bd1f15"><span data-lake-id="u51960dc5" id="u51960dc5">​</span><br></p>
  <p data-lake-id="u3263aa54" id="u3263aa54"><span data-lake-id="u02fe2668" id="u02fe2668">WatchManager是Zookeeper服务端内部的一个模块，用于管理所有watcher的相关操作，包括watcher的注册、注销、触发等。</span></p>
  <p data-lake-id="u7dc803f2" id="u7dc803f2"><span data-lake-id="uf1ad120f" id="uf1ad120f">​</span><br></p>
  <p data-lake-id="u5750f7b3" id="u5750f7b3"><span data-lake-id="u1febefec" id="u1febefec">而ZkWatcherManager是Zookeeper客户端中的一个模块，用于管理客户端中watcher的相关操作，包括创建watcher、注册watcher、处理watcher事件等。</span></p>
  <p data-lake-id="uc8a93f21" id="uc8a93f21"><span data-lake-id="u485fb177" id="u485fb177">​</span><br></p>
  <p data-lake-id="uc22e8d55" id="uc22e8d55"><span data-lake-id="u8269692b" id="u8269692b">（PS：这俩模块所处的位置和职责都不一样，网上很多文章都搞混了，甚至只介绍了其中一个，或者干脆不介绍，所以很多人看完都不懂）</span></p>
  <p data-lake-id="ue0996c7a" id="ue0996c7a"><span data-lake-id="uc010f6fb" id="uc010f6fb">​</span><br></p>
  <p data-lake-id="u6e405bbb" id="u6e405bbb"><span data-lake-id="uff0eeb49" id="uff0eeb49">了解了这几个概念之后，再来说一下ZK的watch机制是如何工作的：</span></p>
  <p data-lake-id="u9dfeb625" id="u9dfeb625"><span data-lake-id="u330798dd" id="u330798dd">​</span><br></p>
  <ol list="udb736a99">
   <li fid="u2a8afe3d" data-lake-id="u9e901aae" id="u9e901aae"><span data-lake-id="u730922a6" id="u730922a6">客户端连接到Zookeeper服务端，客户端创建一个ZkWatcherManager实例，用于管理客户端中所有的watcher。</span></li>
  </ol>
  <p data-lake-id="u97cb5003" id="u97cb5003"><span data-lake-id="u437ed187" id="u437ed187">​</span><br></p>
  <ol list="udb736a99" start="2">
   <li fid="u2a8afe3d" data-lake-id="ud0775333" id="ud0775333"><span data-lake-id="u7f612639" id="u7f612639">当客户端想要监控某个znode节点时，它可以调用ZkWatcherManager中的方法创建watcher并将其注册到客户端中。客户端将watcher的信息发送到Zookeeper服务端。</span></li>
  </ol>
  <p data-lake-id="uaa1db7c0" id="uaa1db7c0"><span data-lake-id="uae048627" id="uae048627">​</span><br></p>
  <ol list="udb736a99" start="3">
   <li fid="u2a8afe3d" data-lake-id="u6cfabaf5" id="u6cfabaf5"><span data-lake-id="u6b77102f" id="u6b77102f">Zookeeper服务端接收到客户端发送的watcher信息后，会将该watcher信息交给WatchManager处理。WatchManager会将该watcher注册到相应的znode节点上，并将watcher相关的信息保存在内存中。</span></li>
  </ol>
  <p data-lake-id="u542c3974" id="u542c3974"><br></p>
  <p data-lake-id="ubd52dc98" id="ubd52dc98"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1677912683921-9e88d23a-2733-425e-a9b6-a477b4d53b32.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_46%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="u6488dbe7" id="u6488dbe7"><br></p>
  <ol list="udb736a99" start="4">
   <li fid="u2a8afe3d" data-lake-id="ue1a5881e" id="ue1a5881e"><span data-lake-id="u0c445c91" id="u0c445c91">当znode节点发生变化时，WatchManager会通知Zookeeper Server</span></li>
  </ol>
  <p data-lake-id="ufa0489a0" id="ufa0489a0"><br></p>
  <ol list="udb736a99" start="5">
   <li fid="u2a8afe3d" data-lake-id="u96397911" id="u96397911"><span data-lake-id="u30da8c61" id="u30da8c61">Zookeeper Server会根据变化类型通知相应的客户端，告知它们发生了哪些变化。</span></li>
  </ol>
  <p data-lake-id="u22bb7627" id="u22bb7627"><br></p>
  <ol list="udb736a99" start="6">
   <li fid="u2a8afe3d" data-lake-id="u316d6ed5" id="u316d6ed5"><span data-lake-id="ua7b16049" id="ua7b16049">当客户端接收到Zookeeper Server的通知后，ZkWatcherManager会根据watcher的类型（data watcher或child watcher）来触发相应的事件处理方法，例如data watcher会触发processDataChanged()方法，child watcher会触发processChildChanged()方法等。</span></li>
  </ol>
  <p data-lake-id="u9d1db900" id="u9d1db900"><br></p>
  <p data-lake-id="ubc77d6e2" id="ubc77d6e2"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1677913724274-14acefb4-8bc7-4853-9d1b-4c3603ab634f.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_43%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
 </body>
</html>